import numpy as np
import pandas as pd

#打印列数
pd.set_option('display.max_columns',1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth',1000)

df = pd.read_csv("../res/data-csv/boston_housing.csv")
print(df.head())
print(df.info())

###删除y 大于等于50的样本
# print(df.shape)
# df = df[df.MEDV < 50]
# print(df.shape)

#从原始数据分量输入特征X和标签y
y = df['MEDV']
print("-->median:", y)

X = df.drop('MEDV', axis=1)
###对价格做log变换，对
log_y = np.log1p(y)

## RAD的含义是距离高速公路的便利指数。虽然给的数值是数值型，但实际是索引，可换成离散特征/类别型特征编码试试。
X["RAD"].astype('object')
X_cat = X['RAD']
X_cat = pd.get_dummies(X_cat, prefix='RAD')
X = X.drop("RAD", axis=1)
feat_names = X.columns
print(X_cat.head())

'''
3.4. 数值型特征预处理
scikit learn中提供的数据预处理功能： http://scikit-learn.org/stable/modules/preprocessing.html
Boston房价数据集特征均为数值型特征。在数据探索阶段发现，发现各特征差异较大，需要进行数据标准化预处理。 
标准化的目的在于避免原始特征值差异过大，导致训练得到的参数权重单位不一致，无法比较各特征的重要性。
另外，一些优化算法（如随机梯度下降及其改进版本）只在各特征尺度差不多的情况下才能保证收敛。
'''
from sklearn.preprocessing import  StandardScaler
ss_X = StandardScaler()
ss_y = StandardScaler()
ss_log_y = StandardScaler()

# 分别对训练和测试数据的特征以及目标值进行标准化处理
# 对训练数据，先调用fit方法训练模型，得到模型参数；然后对训练数据和测试数据进行transform
X = ss_X.fit_transform(X)
#对y做标准化不是必须
#对y标准化的好处是不同问题的w差异不太大，同时正则参数的范围也有限
print(type(y))
y = ss_y.fit_transform(y.values.reshape(-1, 1))
log_y = ss_y.fit_transform(log_y.values.reshape(-1, 1))

##保持特征工程的结果
fe_data = pd.DataFrame(data=X, columns=feat_names, index = df.index)
fe_data = pd.concat([fe_data, X_cat], axis = 1, ignore_index=False)
#加上标签y
fe_data['MEDV'] = y
fe_data['log_MEDV'] = log_y
fe_data.to_csv("FE_boston.csv", index=False)

print(fe_data.head())
print(fe_data.info())